#include "CEmitter.h"
#include "CParticle.h"
#include "SGD Wrappers/CSGD_TextureManager.h"
#include "SGD Wrappers/SGD_Math.h"

CEmitter::CEmitter()
{
	m_nMaxParticles = 0;
	m_nParticlesOnScreen = 0;
	m_fPosX = 0;
	m_fPosY = 0;
	m_fMinVelX = 0;
	m_fMaxVelX = 0;
	m_fMinVelY = 0;
	m_fMaxVelY = 0;
	m_nImageID = -1;
	m_uistartBlendMode = 0;
	m_uidestBlendMode = 0;
	m_nMaxLifespan = 0;
	m_nMinLifespan = 0;
	Xgrav = 0;
	Ygrav = 0;
	scale = 1;
	startColor.a = 0;
	startColor.r = 0;
	startColor.g = 0;
	startColor.b = 0;
	endColor.a = 0;
	endColor.r = 0;
	endColor.g = 0;
	endColor.b = 0;
	timer = 0;
	m_fEmissionRate = 0.0f;
	clearingList = false;
	Play = false;
	m_nParticleCount = 0;
}
CEmitter::~CEmitter()
{
	ClearLists();
}
void CEmitter::AddParticle()
{
	CParticle* tempParticle = new CParticle();
	if(Spread)
	{
		float angle = (RAND_FLOAT(0, 1) * (SGD_PI * 2));
		tempParticle->Init(m_fPosX, m_fPosY, sin(angle) * m_fMaxVelX, cos(angle) * m_fMaxVelY, (float)m_nMaxLifespan, scale, Xgrav, Ygrav, startColor, endColor);
	}
	else
		tempParticle->Init(m_fPosX, m_fPosY, RAND_FLOAT(m_fMinVelX, m_fMaxVelX), RAND_FLOAT(m_fMinVelY, m_fMaxVelY), RAND_FLOAT(m_nMinLifespan, m_nMaxLifespan),scale,Xgrav,Ygrav,startColor,endColor);
	m_vecliveParticles.push_back(tempParticle);
	m_nParticleCount += 1;
}
void CEmitter::ClearLists()
{
	clearingList = true;
	int i;
	for(i = 0; i < m_nParticleCount; ++i)
	{
		if(m_vecliveParticles.size() > 0)
		{
			delete m_vecliveParticles[0];
			m_vecliveParticles[0] = NULL;
			m_vecliveParticles.erase(m_vecliveParticles.begin());
		}
		else
			break;
	}
	m_vecliveParticles.clear();

	for(i = m_vecdeadParticles.size(); i > 0; i--)
	{
		delete m_vecdeadParticles[0];
		m_vecdeadParticles[0] = NULL;
		m_vecdeadParticles.erase(m_vecdeadParticles.begin());
	}
	m_vecdeadParticles.clear();
}
void CEmitter::Update(float fDelta)
{
	timer += fDelta;
	if(Spread)
	{
		if(timer > 0.75)
		{
			if(Play && !clearingList)
			{
				for (int i = 0; i < 20; ++i)
				{
					AddParticle();
				}
			}
			timer = 0.0f;
		}
	}
	else
	{
		if (timer > m_fEmissionRate)
		{
			if(m_vecdeadParticles.size() > m_nMaxParticles)
			{
				m_vecliveParticles.push_back(m_vecdeadParticles[0]);
				m_vecdeadParticles.erase(m_vecdeadParticles.begin());
			}
			else if(m_vecliveParticles.size() < m_nMaxParticles && !clearingList)
				AddParticle();
			timer = 0.0f;
		}
	}
	
	if(m_vecliveParticles.size() > 0)
    {
		vector<CParticle*>::iterator particle = m_vecliveParticles.begin();
		for(unsigned int i = 0; i < m_vecliveParticles.size(); i++)
		{
			if(m_vecliveParticles[i]->GetAge() >= m_vecliveParticles[i]->GetLifespan())
			{
				m_vecdeadParticles.push_back(m_vecliveParticles[i]);
				m_vecliveParticles.erase(m_vecliveParticles.begin() + i);
			}
			else
				m_vecliveParticles[i]->Update(fDelta);
		}
    }
}
void CEmitter::Render()
{
	DWORD oldSource;
	DWORD oldDest;
	CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->GetRenderState(D3DRS_SRCBLEND, &oldSource);
	CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->GetRenderState(D3DRS_DESTBLEND, &oldDest);
	CSGD_Direct3D::GetInstance()->GetSprite()->Flush();
	CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO + m_uistartBlendMode);
	CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND , D3DBLEND_ZERO + m_uidestBlendMode);
	
	for (unsigned int particle = 0; particle < m_vecliveParticles.size(); ++particle)
    {
		int alpha = (int)m_vecliveParticles[particle]->GetCurrColor().a;
		int red = (int)m_vecliveParticles[particle]->GetCurrColor().r;
		int green =  (int)m_vecliveParticles[particle]->GetCurrColor().g;
		int blue = (int)m_vecliveParticles[particle]->GetCurrColor().b;
		
		CSGD_TextureManager::GetInstance()->Draw(m_nImageID, (int)m_vecliveParticles[particle]->GetPosX(), (int)m_vecliveParticles[particle]->GetPosY(), m_vecliveParticles[particle]->GetScale(), m_vecliveParticles[particle]->GetScale(), 0, 0, 0, 0, D3DCOLOR_ARGB(alpha,red,green,blue));
    }
	
	CSGD_Direct3D::GetInstance()->GetSprite()->Flush();
	CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, oldSource);
	CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, oldDest);
}